package com.mycat.dao.base;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;

public abstract class BaseDao<O> {

	@Resource
	private SqlSessionTemplate sqlSessionTemplate;
	
	/**
	 * 获取当前xml的namespace
	 * @return String
	 */
	protected abstract String getNameSpace();

	protected int count(String statementName) {
		Integer count = this.getObject(statementName);
		return count.intValue();
	}

	protected int count(String statementName, Object paramObj) {
		Integer count = this.getObject(statementName, paramObj);
		return count.intValue();
	}

	protected int delete(String statementName) {
		return sqlSessionTemplate.delete(getNameSpace() + "." + statementName);
	}

	protected int delete(String statementName, Object paramObj) {
		return sqlSessionTemplate.delete(getNameSpace() + "." + statementName, paramObj);
	}

	protected int insert(String statementName) {
		return sqlSessionTemplate.insert(getNameSpace() + "." + statementName);
	}

	protected int insert(String statementName, Object paramObj) {
		return sqlSessionTemplate.insert(getNameSpace() + "." + statementName, paramObj);
	}

	protected int update(String statementName) {
		return sqlSessionTemplate.update(getNameSpace() + "." + statementName);
	}

	protected int update(String statementName, Object paramObj) {
		return sqlSessionTemplate.update(getNameSpace() + "." + statementName, paramObj);
	}

	protected <O> O getObject(String statementName) {
		return sqlSessionTemplate.selectOne(getNameSpace() + "." + statementName);
	}

	protected <O> O getObject(String statementName, Object paramObj) {
		return sqlSessionTemplate.selectOne(getNameSpace() + "." + statementName, paramObj);
	}

	protected <O> List<O> getObjectList(String statementName) {
		return sqlSessionTemplate.selectList(getNameSpace() + "." + statementName);
	}

	protected <O> List<O> getObjectList(String statementName, Object paramObj) {
		return sqlSessionTemplate.selectList(getNameSpace() + "." + statementName, paramObj);
	}

	protected <K, V> Map<K, V> getObjectMap(String statementName, String mapKey) {
		return sqlSessionTemplate.selectMap(getNameSpace() + "." + statementName, mapKey);
	}

	protected <K, V> Map<K, V> getObjectMap(String statementName, Object paramObj, String mapKey) {
		return sqlSessionTemplate.selectMap(getNameSpace() + "." + statementName, paramObj, mapKey);
	}

	protected int truncate(String statementName) {
		return delete(statementName);
	}

	protected final <O> boolean batchDelete(final String statementName, final List<O> list) {
		boolean rt = true;
		// 此代码没有使用spring的事务,改动手动控制,如果和原spring事务一起使用,将无法回滚,必须注意,最好单独使用;
		SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		int size = list.size();
		try {
			for (int i = 0; i < size; i++) {
				O paramObj = list.get(i);
				sqlSession.delete(getNameSpace() + "." + statementName, paramObj);
				if ((i + 1) % 200 == 0 || (i + 1) == (size)) {
					// 手动每200条提交一次,提交后无法回滚
					sqlSession.commit();
					// 清理缓存，防止溢出
					sqlSession.clearCache();
				}
			}
		} catch (Exception e) {
			// 没有提交的数据可以回滚
			sqlSession.rollback();
			rt = false;
		} finally {
			sqlSession.close();
		}
		return rt;
	}

	protected final <O> boolean batchCallback(final String statementName, final List<O> list) {
		boolean rt = true;
		// 此代码没有使用spring的事务,改动手动控制,如果和原spring事务一起使用,将无法回滚,必须注意,最好单独使用;
		SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		int size = list.size();
		try {
			for (int i = 0; i < size; i++) {
				O paramObj = list.get(i);
				sqlSession.selectOne(getNameSpace() + "." + statementName, paramObj);
				if ((i + 1) % 200 == 0 || (i + 1) == (size)) {
					// 手动每200条提交一次,提交后无法回滚
					sqlSession.commit();
					// 清理缓存，防止溢出
					sqlSession.clearCache();
				}
			}
		} catch (Exception e) {
			// 没有提交的数据可以回滚
			sqlSession.rollback();
			rt = false;
		} finally {
			sqlSession.close();
		}
		return rt;
	}

	protected final <O> boolean batchInsert(final String statementName, final List<O> list) {
		boolean rt = true;
		// 此代码没有使用spring的事务,改动手动控制,如果和原spring事务一起使用,将无法回滚,必须注意,最好单独使用;
		SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		int size = list.size();
		try {
			for (int i = 0; i < size; i++) {
				O paramObj = list.get(i);
				sqlSession.insert(getNameSpace() + "." + statementName, paramObj);
				if ((i + 1) % 200 == 0 || (i + 1) == (size)) {
					// 手动每200条提交一次,提交后无法回滚
					sqlSession.commit();
					// 清理缓存，防止溢出
					sqlSession.clearCache();
				}
			}
		} catch (Exception e) {
			// 没有提交的数据可以回滚
			sqlSession.rollback();
			rt = false;
		} finally {
			sqlSession.close();
		}
		return rt;
	}

	protected final <O> boolean batchUpdate(final String statementName, final List<O> list) {
		boolean rt = true;
		// 此代码没有使用spring的事务,改动手动控制,如果和原spring事务一起使用,将无法回滚,必须注意,最好单独使用;
		SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		int size = list.size();
		try {
			for (int i = 0; i < size; i++) {
				O paramObj = list.get(i);
				sqlSession.update(getNameSpace() + "." + statementName, paramObj);
				if ((i + 1) % 200 == 0 || (i + 1) == (size)) {
					// 手动每200条提交一次,提交后无法回滚
					sqlSession.commit();
					// 清理缓存，防止溢出
					sqlSession.clearCache();
				}
			}
		} catch (Exception e) {
			// 没有提交的数据可以回滚
			sqlSession.rollback();
			rt = false;
		} finally {
			sqlSession.close();
		}
		return rt;
	}

}
